package tbpay

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"

	"gitee.com/liuxuezhan/ar-platform/assets-api/internal/pay/base"
)

type Factory struct {
}

func (p *Factory) CreatePay(config base.Config) base.Payment {
	return &TBPay{
		Url:        config.Url,
		MerchantId: config.MerchantId,
		SecretKey:  config.SecretKey,
		ReturnUrl:  config.ReturnUrl,
		NotifyUrl:  config.NotifyUrl,
	}
}

type TBPay struct {
	Url        string `json:"url"`         // 网关//
	MerchantId string `json:"merchant_id"` // 商户账号
	SecretKey  string `json:"secret_key"`  // 代收秘钥
	ReturnUrl  string `json:"return_url"`
	NotifyUrl  string `json:"notify_url"`
}

// Response represents the structure of the response from the API
type Response struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		OrderID    string `json:"orderId"`
		OrderNo    string `json:"orderNo"`
		PaymentURL string `json:"paymentUrl"`
	} `json:"data"`
}

func (t *TBPay) Pay(ctx context.Context, params map[string]interface{}) (base.PayResponse, error) {
	amount, ok := params["amount"].(float64)
	if !ok {
		return base.PayResponse{}, fmt.Errorf("amount type invalid")
	}
	data := map[string]interface{}{
		"merchantNo":  t.MerchantId,
		"payType":     "1",
		"orderNo":     params["orderNo"],
		"notifyUrl":   t.NotifyUrl,
		"orderAmount": fmt.Sprintf("%.2f", amount),
		"signType":    "AES",
		"version":     "1.0",
		"goods":       "Recharge",
		"memberId":    "120",
	}

	sign, err := t.RechargeSign(data)
	if err != nil {
		return base.PayResponse{}, err
	}
	data["sign"] = sign
	payUrl := t.Url + "/apiOrder/pay"
	response, err := t.send(ctx, payUrl, data)
	if err != nil {
		return base.PayResponse{}, err
	}

	return base.PayResponse{
		Url:     response.Data.PaymentURL,
		Address: "",
		OrderNo: response.Data.OrderID,
	}, nil
}

func (t *TBPay) RechargeSign(params map[string]interface{}) (string, error) {
	encrypt, err := EncryptData(params, []byte(t.SecretKey))
	if err != nil {
		return "", err
	}
	return encrypt, nil
}

// 发送请求，处理返回数据
func (t *TBPay) send(ctx context.Context, payUrl string, data map[string]interface{}) (Response, error) {
	resp, err := base.SendPostJson(ctx, payUrl, data)
	if err != nil {
		return Response{}, err
	}

	// Parse the JSON response
	var response Response
	err = json.Unmarshal([]byte(resp), &response)
	if err != nil {
		return Response{}, err
	}

	// 返回结果处理
	if response.Code != 200 {
		return Response{}, errors.New(response.Message)
	}

	return response, nil
}
